﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Profile;
using COFE.Core;

namespace COFE.Core.Lister
{
    public class DirectoryControllerBase : IDirectoryController
    {
        #region Constructor

        public DirectoryControllerBase(IDirectoryLister directoryLister)
        {
            _directoryLister = directoryLister;
        }

        #endregion

        #region Methods        

        public IInternalFileInfoExA CreateFile(IInternalDirectoryInfoExA parent, string fileName)
        {
            return _createFile(parent, fileName);
        }

        public IInternalDirectoryInfoExA CreateDirectory(IInternalDirectoryInfoExA parent, string dirName)
        {
            return _createDirectory(parent, dirName);
        }

        public void Rename(IInternalFileSystemInfoExA entry, string newName)
        {
            _rename(entry, newName);
        }

        public void Copy(IInternalFileSystemInfoExA entry, IInternalDirectoryInfoExA targetDir, bool raiseAlert)
        {
            _copy(entry, targetDir);
        }

        public void Move(IInternalFileSystemInfoExA entry, IInternalDirectoryInfoExA targetDir, bool raiseAlert)
        {
            //Both source and target are within same directory volume.
            if (_move != null && entry.ListerKey == ListerKey)
            {
                _move(entry, targetDir);
            }
            else
            {
                Copy(entry, targetDir, raiseAlert);
                entry.Delete();
                NotifyModified(entry.ParseName, entry.IsFolder, ModifiedAction.Deleted);
            }
        }

        public void Delete(IInternalFileSystemInfoExA entry, bool raiseAlert)
        {
            _delete(entry);
        }

        public void NotifyModified(string parsePath, bool isFolder, ModifiedAction action, string oldParsePath = null)
        {
            if (_notifyModified != null)
            {
                IInternalFileSystemInfoExA entry = COFEShared.PathParser.TryParsePath(parsePath, ParsableType.ParsePath) as IInternalFileSystemInfoExA;
                if (entry != null)
                    NotifyModified(entry, action, oldParsePath);
            }
            else
            {
                if (action == ModifiedAction.Renamed)
                    OnFileSystemModified(this, new Logger.RenameEventArgsExA(ListerKey, action, isFolder, parsePath, oldParsePath));
                else
                    OnFileSystemModified(this, new Logger.FileSystemEventArgsExA(ListerKey, action, isFolder, parsePath));
            }

        }

        public void NotifyModified(IInternalFileSystemInfoExA entry, ModifiedAction action, string oldParsePath = null)
        {
            //Console.WriteLine(String.Format("[{0}] - {1}", action, entries.ToString()));
            if (_notifyModified != null)            
                _notifyModified(entry, action);            

            if (action == ModifiedAction.Renamed)
                OnFileSystemModified(this, new Logger.RenameEventArgsExA(ListerKey, action, entry.IsFolder, entry.ParseName, oldParsePath));
            else
                OnFileSystemModified(this, new Logger.FileSystemEventArgsExA(ListerKey, action, entry.IsFolder, entry.ParseName));
        }

        #endregion

        #region Data

        protected Func<IInternalDirectoryInfoExA, string, IInternalFileInfoExA> _createFile = (item, name) => { throw new NotImplementedException(); };
        protected Func<IInternalDirectoryInfoExA, string, IInternalDirectoryInfoExA> _createDirectory = (item, name) => { throw new NotImplementedException(); };
        protected Action<IInternalFileSystemInfoExA, string> _rename = (item, name) => { throw new NotImplementedException(); };
        protected Action<IInternalFileSystemInfoExA, ModifiedAction> _notifyModified = null;
        protected Action<IInternalFileSystemInfoExA, IInternalDirectoryInfoExA> _copy = (item, newDir) => { throw new NotImplementedException(); };
        protected Action<IInternalFileSystemInfoExA, IInternalDirectoryInfoExA> _move = (item, newDir) => { throw new NotImplementedException(); };
        protected Action<IInternalFileSystemInfoExA> _delete = (item) => { throw new NotImplementedException(); };

        protected IDirectoryLister _directoryLister;

        public event EventHandler<Logger.FileSystemEventArgsExA> OnFileSystemModified;

        #endregion

        #region Public Properties

        public string ListerKey { get { return _directoryLister.ListerKey; } }

        #endregion
    
    }
}
